const express = require("express");
const { exec } = require("child_process");
const util = require("util");
const axios = require("axios");
const jwt = require("jsonwebtoken");

const toml = require("@iarna/toml");
const fs = require("fs-extra");
const path = require("path");

const app = express();
const port = 8000;
const execPromise = util.promisify(exec);

// JWT 密钥
const JWT_SECRET = "himalaya-mail-secret-key"; // 在生产环境中应该使用环境变量存储
const JWT_EXPIRES_IN = "24h"; // Token 有效期

// 添加 JSON 解析中间件
app.use(express.json());

// 存储临时配置的目录
const CONFIG_DIR = path.join(__dirname, "himalaya_configs");

// 解析 Himalaya 输出
function parseHimalayaOutput(stdout) {
  console.log("解析 Himalaya 输出...");
  console.log("原始输出:", stdout);

  // 检查是否为空输出
  if (!stdout || stdout.trim() === "") {
    console.warn("没有输出内容可解析");
    return [];
  }

  const emails = [];
  const lines = stdout.split("\n");

  console.log("总行数:", lines.length);

  // 找到数据开始的位置（跳过表头和分隔行）
  let dataStartIndex = 0;
  let hasHeader = false;

  for (let i = 0; i < lines.length; i++) {
    console.log(`检查第 ${i} 行:`, lines[i]);

    // 检查是否是表头行
    if (lines[i].includes("| ID | FLAGS | SUBJECT")) {
      hasHeader = true;
      console.log("找到表头行");
    }

    // 检查是否是分隔行
    if (lines[i].includes("|----|")) {
      dataStartIndex = i + 1;
      console.log("找到分隔行，数据从第", dataStartIndex, "行开始");
      break;
    }
  }

  // 如果没有找到表头或分隔行，可能格式不同
  if (!hasHeader) {
    console.log("没有找到标准表头，尝试直接解析每一行");
    // 尝试解析每一行
    for (let i = 0; i < lines.length; i++) {
      const line = lines[i].trim();
      if (!line) continue;

      console.log(`尝试解析行: ${line}`);
      // 尝试不同的分隔符
      let fields = [];
      if (line.includes("|")) {
        fields = line
          .split("|")
          .map((f) => f.trim())
          .filter((f) => f);
      } else {
        fields = line.split(/\s+/).filter((f) => f);
      }

      console.log("解析出的字段:", fields);

      if (fields.length >= 3) {
        // 尝试提取基本信息
        const email = {
          id: fields[0] || "未知ID",
          subject: fields.length > 2 ? fields[2] : "未知主题",
          from: fields.length > 1 ? fields[1] : "未知发件人",
          date: fields.length > 3 ? fields[3] : "未知日期",
        };
        console.log("添加邮件:", email);
        emails.push(email);
      }
    }

    console.log(`成功解析 ${emails.length} 封邮件`);
    return emails;
  }

  // 只处理实际的数据行
  for (let i = dataStartIndex; i < lines.length; i++) {
    const line = lines[i].trim();
    console.log(`处理第 ${i} 行:`, line);

    if (!line) {
      console.log("跳过空行");
      continue;
    }

    // 修改字段解析逻辑，保留空字段
    const fields = line.split("|").map((f) => f.trim());

    // 移除第一个和最后一个空字段（由行首和行尾的 | 产生）
    fields.shift();
    fields.pop();

    console.log("解析后的字段:", fields);

    if (fields.length >= 5) {
      const email = {
        id: fields[0],
        flags: fields[1],
        subject: fields[2],
        from: fields[3],
        date: fields[4],
      };
      console.log("添加邮件:", email);
      emails.push(email);
    } else {
      console.log("字段数量不足，跳过该行");
    }
  }

  console.log(`成功解析 ${emails.length} 封邮件`);
  return emails;
}

// 生成用户特定的 Himalaya 配置文件
async function createUserConfig(email, appSpecificPassword) {
  const userConfigDir = path.join(CONFIG_DIR, email.replace("@", "_")); // 避免非法文件名
  const configPath = path.join(userConfigDir, "config.toml");

  console.log("正在创建配置文件...");
  console.log("配置目录:", userConfigDir);
  console.log("配置文件路径:", configPath);

  // 确保目录存在
  await fs.ensureDir(userConfigDir);
  console.log("配置目录已创建");

  // 直接创建 TOML 字符串，根据用户原始配置
  const tomlContent = `
[accounts.icloud]
default = true
email = "${email}"
display-name = "${email.split("@")[0]}"
signature = "Regards,\\n"
signature-delim = "-- \\n"
downloads-dir = "/root/Downloads"
backend.type = "imap"
backend.host = "imap.mail.me.com"
backend.port = 993
backend.login = "${email}"
backend.encryption.type = "tls"
backend.auth.type = "password"
backend.auth.raw = "${appSpecificPassword}"
message.send.backend.type = "smtp"
message.send.backend.host = "smtp.mail.me.com"
message.send.backend.port = 587
message.send.backend.login = "${email}"
message.send.backend.encryption.type = "start-tls"
message.send.backend.auth.type = "password"
message.send.backend.auth.raw = "${appSpecificPassword}"
folder.aliases.inbox = "INBOX"
folder.aliases.sent = "Sent Messages"
folder.aliases.drafts = "Drafts"
folder.aliases.trash = "Deleted Messages"
folder.aliases.junk = "Junk"
folder.aliases.archive = "Archive"
`;

  console.log("生成的 TOML 内容:", tomlContent);

  await fs.writeFile(configPath, tomlContent);
  console.log("配置文件已写入");

  // 验证文件是否成功创建
  const fileExists = await fs.pathExists(configPath);
  if (!fileExists) {
    throw new Error("配置文件创建失败");
  }

  return configPath;
}

// 获取用户邮件
async function getUserEmails(email, configPath) {
  try {
    console.log("使用配置文件:", configPath);
    const { stdout, stderr } = await execPromise(
      `himalaya envelope list -c "${configPath}" --account icloud  --folder "Sent Messages"`
    );

    console.log("Himalaya 原始输出:", stdout);

    if (stderr) {
      console.warn(`Himalaya 警告信息: ${stderr}`);
      // 警告通常不影响功能
    }

    if (!stdout || stdout.trim() === "") {
      console.warn("Himalaya 没有返回任何输出");
      return [];
    }

    return parseHimalayaOutput(stdout);
  } catch (error) {
    console.error(`Himalaya error for ${email}: ${error.message}`);
    return [];
  }
}

// 验证 JWT Token 的中间件
function authenticateToken(req, res, next) {
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({ error: "未提供认证令牌" });
  }

  jwt.verify(token, JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(403).json({ error: "令牌无效或已过期" });
    }

    req.user = user;
    next();
  });
}

// 登录路由
app.post("/login", async (req, res) => {
  const { email, appSpecificPassword } = req.body;

  if (!email || !appSpecificPassword) {
    return res.status(400).json({ error: "邮箱和密码不能为空" });
  }

  try {
    // 生成用户配置文件
    const configPath = await createUserConfig(email, appSpecificPassword);

    // 测试配置是否有效
    try {
      const { stdout, stderr } = await execPromise(
        `himalaya envelope list -c "${configPath}" --account icloud  --folder "INBOX" --limit 1`
      );

      if (stderr && stderr.includes("error")) {
        console.error(`验证失败: ${stderr}`);
        await fs.remove(path.dirname(configPath));
        return res.status(401).json({ error: "邮箱或密码错误" });
      }
    } catch (error) {
      console.error(`验证失败: ${error.message}`);
      await fs.remove(path.dirname(configPath));
      return res.status(401).json({ error: "邮箱或密码错误" });
    }

    // 生成 JWT Token
    const token = jwt.sign({ email, configPath }, JWT_SECRET, {
      expiresIn: JWT_EXPIRES_IN,
    });

    res.json({
      message: "登录成功",
      token,
      email,
    });
  } catch (error) {
    console.error(`登录错误: ${error.message}`);
    res.status(500).json({ error: "服务器内部错误" });
  }
});

// 获取邮件路由（需要认证）
app.get("/emails", authenticateToken, async (req, res) => {
  try {
    const { email, configPath } = req.user;

    // 检查配置文件是否存在
    const fileExists = await fs.pathExists(configPath);
    if (!fileExists) {
      // 如果配置文件不存在，重新生成
      return res.status(401).json({
        error: "配置文件不存在，请重新登录",
        code: "CONFIG_NOT_FOUND",
      });
    }

    // 获取邮件
    const emails = await getUserEmails(email, configPath);
    res.json(emails);
  } catch (error) {
    console.error(`获取邮件错误: ${error.message}`);
    res.status(500).json({ error: "服务器内部错误" });
  }
});

// 退出登录
app.post("/logout", authenticateToken, async (req, res) => {
  try {
    const { configPath } = req.user;

    // 删除配置文件
    await fs.remove(path.dirname(configPath));

    res.json({ message: "退出成功" });
  } catch (error) {
    console.error(`退出错误: ${error.message}`);
    res.status(500).json({ error: "服务器内部错误" });
  }
});

// 保留旧的 API 路由以兼容
app.get("/sent-emails", async (req, res) => {
  try {
    console.log("收到获取已发送邮件的请求（旧 API）");
    res.status(400).json({ error: "此 API 已弃用，请使用新的认证 API" });
  } catch (error) {
    console.error("API 错误:", error.message);
    res.status(500).json({ error: "Internal server error" });
  }
});

// 保留旧的 API 路由以兼容
app.post("/emails", async (req, res) => {
  console.log("收到旧版 API 请求，建议使用新的登录和邮件获取 API");
  const { email, appSpecificPassword } = req.body;

  if (!email || !appSpecificPassword) {
    return res.status(400).json({ error: "Email and password required" });
  }

  try {
    // 生成用户配置文件
    const configPath = await createUserConfig(email, appSpecificPassword);

    // 获取邮件
    const emails = await getUserEmails(email, configPath);

    // 可选：删除临时配置文件
    await fs.remove(path.dirname(configPath));

    res.json(emails);
  } catch (error) {
    console.error(`Error for ${email}: ${error.message}`);
    res.status(500).json({ error: "Internal server error" });
  }
});

// 启动服务
app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});
